﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service.Util
{
    public class SymmetrySecret
    {
        private string _CryptText;
        private byte[] _CryptKey;
        private byte[] _CryptIV;
        public string CryptText
        {
            get
            {
                return this._CryptText;
            }
            set
            {
                this._CryptText = value;
            }
        }
        public byte[] CryptKey
        {
            get
            {
                return this._CryptKey;
            }
            set
            {
                this._CryptKey = value;
            }
        }
        public byte[] CryptIV
        {
            get
            {
                return this._CryptIV;
            }
            set
            {
                this._CryptIV = value;
            }
        }
        public SymmetrySecret(string cryptText, byte[] cryptKey, byte[] cryptIV)
        {
            this.CryptText = cryptText;
            this.CryptKey = cryptKey;
            this.CryptIV = cryptIV;
        }
        public SymmetrySecret(string cryptText, string key, string IV)
        {
            this.CryptText = cryptText;
            this.CryptKey = System.Convert.FromBase64String(key);
            this.CryptIV = System.Convert.FromBase64String(IV);
        }
        public SymmetrySecret(string cryptText)
        {
            this.CryptText = cryptText;
            this.CryptKey = System.Convert.FromBase64String("0t3q4fHJnyAVndj66+gBmmj6FkemW3xt/7uOgMHoKLg=");
            this.CryptIV = System.Convert.FromBase64String("DZVKpnvwxRhErICEoMTTOw==");
        }

        public SymmetrySecret()
        {
            this.CryptKey = System.Convert.FromBase64String("0t3q4fHJnyAVndj66+gBmmj6FkemW3xt/7uOgMHoKLg=");
            this.CryptIV = System.Convert.FromBase64String("DZVKpnvwxRhErICEoMTTOw==");
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <returns></returns>
        public string Encrypt()
        {
            string cryptText = this.CryptText;
            byte[] cryptKey = this.CryptKey;
            byte[] cryptIV = this.CryptIV;
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(cryptText);
            System.Security.Cryptography.RijndaelManaged rijndaelManaged = new System.Security.Cryptography.RijndaelManaged();
            System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
            System.Security.Cryptography.CryptoStream cryptoStream = new System.Security.Cryptography.CryptoStream(memoryStream, rijndaelManaged.CreateEncryptor(cryptKey, cryptIV), System.Security.Cryptography.CryptoStreamMode.Write);
            cryptoStream.Write(bytes, 0, bytes.Length);
            cryptoStream.FlushFinalBlock();
            return System.Convert.ToBase64String(memoryStream.ToArray());
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <returns></returns>
        public string Encrypt(string cryptText)
        {
            byte[] cryptKey = this.CryptKey;
            byte[] cryptIV = this.CryptIV;
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(cryptText);
            System.Security.Cryptography.RijndaelManaged rijndaelManaged = new System.Security.Cryptography.RijndaelManaged();
            System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
            System.Security.Cryptography.CryptoStream cryptoStream = new System.Security.Cryptography.CryptoStream(memoryStream, rijndaelManaged.CreateEncryptor(cryptKey, cryptIV), System.Security.Cryptography.CryptoStreamMode.Write);
            cryptoStream.Write(bytes, 0, bytes.Length);
            cryptoStream.FlushFinalBlock();
            return System.Convert.ToBase64String(memoryStream.ToArray());
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <returns></returns>
        public string Decrypt()
        {
            string cryptText = this.CryptText;
            byte[] cryptKey = this.CryptKey;
            byte[] cryptIV = this.CryptIV;
            byte[] array = System.Convert.FromBase64String(cryptText);
            System.Security.Cryptography.RijndaelManaged rijndaelManaged = new System.Security.Cryptography.RijndaelManaged();
            System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
            System.Security.Cryptography.CryptoStream cryptoStream = new System.Security.Cryptography.CryptoStream(memoryStream, rijndaelManaged.CreateDecryptor(cryptKey, cryptIV), System.Security.Cryptography.CryptoStreamMode.Write);
            cryptoStream.Write(array, 0, array.Length);
            cryptoStream.FlushFinalBlock();
            return System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="cryptText"></param>
        /// <returns></returns>
        public string Decrypt(string cryptText)
        {
            byte[] cryptKey = this.CryptKey;
            byte[] cryptIV = this.CryptIV;
            byte[] array = System.Convert.FromBase64String(cryptText);
            System.Security.Cryptography.RijndaelManaged rijndaelManaged = new System.Security.Cryptography.RijndaelManaged();
            System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
            System.Security.Cryptography.CryptoStream cryptoStream = new System.Security.Cryptography.CryptoStream(memoryStream, rijndaelManaged.CreateDecryptor(cryptKey, cryptIV), System.Security.Cryptography.CryptoStreamMode.Write);
            cryptoStream.Write(array, 0, array.Length);
            cryptoStream.FlushFinalBlock();
            return System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
        }

        #region 是否base64字符串

        private static char[] base64CodeArray = new char[]
        {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            '0', '1', '2', '3', '4',  '5', '6', '7', '8', '9', '+', '/', '='
        };

        /// <summary>
        /// 是否base64字符串
        /// </summary>
        /// <param name="base64Str">要判断的字符串</param>
        /// <returns></returns>
        public static bool IsBase64(string base64Str)
        {
            byte[] bytes = null;
            return IsBase64(base64Str, out bytes);
        }

        /// <summary>
        /// 是否base64字符串
        /// </summary>
        /// <param name="base64Str">要判断的字符串</param>
        /// <param name="bytes">字符串转换成的字节数组</param>
        /// <returns></returns>
        public static bool IsBase64(string base64Str, out byte[] bytes)
        {
            //string strRegex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
            bytes = null;
            if (string.IsNullOrEmpty(base64Str))
                return false;
            else
            {
                if (base64Str.Contains(","))
                    base64Str = base64Str.Split(',')[1];
                if (base64Str.Length % 4 != 0)
                    return false;
                if (base64Str.Any(c => !base64CodeArray.Contains(c)))
                    return false;
            }
            try
            {
                bytes = Convert.FromBase64String(base64Str);
                return true;
            }
            catch (FormatException)
            {
                return false;
            }
        }

        /// <summary>
        /// 是否base64字符串(简化)
        /// </summary>
        /// <param name="base64Str">要判断的字符串</param>
        /// <returns></returns>
        public static bool IsBase64Simplify(string base64Str)
        {
            byte[] bytes = null;
            return IsBase64Simplify(base64Str, out bytes);
        }

        /// <summary>
        /// 是否base64字符串(简化)
        /// </summary>
        /// <param name="base64Str">要判断的字符串</param>
        /// <param name="bytes">字符串转换成的字节数组</param>
        /// <returns></returns>
        public static bool IsBase64Simplify(string base64Str, out byte[] bytes)
        {
            //string strRegex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
            bytes = null;
            if (string.IsNullOrEmpty(base64Str))
                return false;
            else
            {
                if (base64Str.Contains(","))
                    base64Str = base64Str.Split(',')[1];
                //if (base64Str.Length % 4 != 0)
                //	return false;
                //if (base64Str.Any(c => !base64CodeArray.Contains(c)))
                //	return false;
            }
            try
            {
                bytes = Convert.FromBase64String(base64Str);
                return true;
            }
            catch (FormatException)
            {
                return false;
            }
        }

        #endregion
    }
}
